package com.ozo.cloud.gen.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ozo.cloud.common.base.model.BaseBatchDTO;
import com.ozo.cloud.common.base.model.BasePage;
import com.ozo.cloud.common.base.model.PageResult;
import com.ozo.cloud.common.core.exception.ServiceException;
import com.ozo.cloud.common.database.util.SortUtils;
import com.ozo.cloud.gen.entity.GenColumnMap;
import com.ozo.cloud.gen.exception.GenExceptionEnum;
import com.ozo.cloud.gen.mapper.GenColumnMapMapper;
import com.ozo.cloud.gen.pojo.dto.GenColumnMapQueryDTO;
import com.ozo.cloud.gen.pojo.dto.GenColumnMapSaveDTO;
import com.ozo.cloud.gen.service.IGenColumnMapService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 字段类型映射 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @since 2024-11-12
 */
@RequiredArgsConstructor
@Service
public class GenColumnMapServiceImpl extends ServiceImpl<GenColumnMapMapper, GenColumnMap> implements IGenColumnMapService {

    private final DataSource dataSource;

    @Override
    public void add(GenColumnMapSaveDTO saveDTO) {
        // 参数校验
        this.checkParam(null, saveDTO.getDbType(), saveDTO.getJavaType());

        GenColumnMap genColumnMap = BeanUtil.copyProperties(saveDTO, GenColumnMap.class);
        baseMapper.insert(genColumnMap);
    }

    @Override
    public void remove(BaseBatchDTO<Long> batchDTO) {
        baseMapper.deleteBatchIds(batchDTO.getIdList());
    }

    /**
     * 合法性校验
     *
     * @param id
     * @param dbType
     * @param javaType
     */
    private void checkParam(Long id, String dbType, String javaType) {
        LambdaQueryWrapper<GenColumnMap> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GenColumnMap::getDbType, dbType)
                .eq(GenColumnMap::getJavaType, javaType)
                .ne(Objects.nonNull(id), GenColumnMap::getId, id);
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ServiceException(GenExceptionEnum.FIELD_TYPE_NOT_REPEAT);
        }
    }

    @Override
    public void edit(GenColumnMapSaveDTO saveDTO) {
        // 参数校验
        this.checkParam(saveDTO.getId(), saveDTO.getDbType(), saveDTO.getJavaType());

        GenColumnMap genColumnMap = BeanUtil.copyProperties(saveDTO, GenColumnMap.class);
        baseMapper.updateById(genColumnMap);
    }

    @Override
    public PageResult<GenColumnMap> page(BasePage basePage, GenColumnMapQueryDTO queryDTO) {
        Integer pageNum = basePage.getPageNum();
        Integer pageSize = basePage.getPageSize();

        QueryWrapper<GenColumnMap> queryWrapper = new QueryWrapper<>();
        // 排序
        String order = basePage.getOrder();
        if (StrUtil.isBlank(order)) {
            queryWrapper.lambda().orderByDesc(GenColumnMap::getId);
        } else {
            SortUtils.setSortCondition(queryWrapper, basePage.getProp(), order);
        }
        // 条件
        queryWrapper.lambda()
                .like(StrUtil.isNotBlank(queryDTO.getColumnType()), GenColumnMap::getColumnType, queryDTO.getColumnType())
                .eq(StrUtil.isNotBlank(queryDTO.getDbType()), GenColumnMap::getDbType, queryDTO.getDbType());
        Page<GenColumnMap> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);

        PageResult<GenColumnMap> pageResult = new PageResult<>();
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);
        pageResult.setPage(page.getPages());
        pageResult.setTotal(page.getTotal());
        pageResult.setResults(page.getRecords());
        return pageResult;
    }

    @Override
    public List<GenColumnMap> list(GenColumnMapQueryDTO queryDTO) {
        String dbType = queryDTO.getDbType();
        if (StrUtil.isBlank(dbType)) {
            try {
                dbType = dataSource.getConnection().getMetaData().getDatabaseProductName();
            } catch (SQLException e) {
                return List.of();
            }
        }
        LambdaQueryWrapper<GenColumnMap> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GenColumnMap::getDbType, dbType)
                .like(StrUtil.isNotBlank(queryDTO.getColumnType()), GenColumnMap::getColumnType, queryDTO.getColumnType());
        return baseMapper.selectList(queryWrapper);
    }
}
